home *** CD-ROM | disk | FTP | other *** search
/ Aminet 8 / Aminet 8 (1995)(GTI - Schatztruhe)[!][Oct 1995].iso / Aminet / util / cdity / Yak210src.lha / Yak_2.10_Src / WBStartup / Hotkey_actions.c < prev    next >
C/C++ Source or Header  |  1995-08-17  |  29KB  |  1,342 lines

  1.  
  2. #define __USE_SYSBASE
  3.  
  4.  
  5. #include <proto/exec.h>
  6. #include <proto/dos.h>
  7. #include <proto/graphics.h>
  8. #include <proto/intuition.h>
  9. #include <proto/commodities.h>
  10. #include <proto/locale.h>
  11. #include <proto/reqtools.h>
  12.  
  13. #include <clib/alib_protos.h>
  14.  
  15. #include <exec/types.h>
  16. #include <exec/tasks.h>
  17. #include <dos/dostags.h>
  18. #include <dos/datetime.h>
  19. #include <intuition/intuitionbase.h>
  20. #include <libraries/locale.h>
  21. #include <libraries/reqtools.h>
  22.  
  23. #include <string.h>
  24.  
  25. #include "code.h"
  26. #include "yak.h"
  27. #include "hotkey_types.h"
  28. #include "Handlers.h"
  29. #include "Settings.h"
  30. #include "Requesters.h"
  31. #include "GetScreenBox.h"
  32. #include "GetPubScreen.h"
  33. #include "Arexx.h"
  34. #include "LastActiveWindow.h"
  35.  
  36. #ifndef USE_WB2CLI
  37. #  include "wbpath.h"
  38. #endif
  39.  
  40. #define CATCOMP_NUMBERS
  41. #include "yak_locale_strings.h"
  42.  
  43. IMPORT BOOL ShowYakInterface (VOID);
  44.  
  45. static void __regargs YakMoveScreen(struct Screen *scr, UWORD flags);
  46. static void __regargs EnlargeWindow(struct Window *win, UWORD flags);
  47. static void ChangeScreen(YakOption *opt);
  48. static struct Window *SelectWindow(YakOption *opt);
  49. static struct Screen *SelectScreen(YakOption *opt);
  50. static SAVEDS ASM void putcharfunc( REG(a0) struct Hook *h,
  51.                                     REG(a2) void *object,
  52.                                     REG(a1) char c);
  53. static struct InputEvent *FlipIEvents(struct InputEvent *);
  54. static int AddToStream(char *str, UBYTE delay); 
  55. static struct Window * FindWBWindow(void);
  56. static SAVEDS void  DoPalette(void);
  57. static int palette_count;
  58. static LONG beginCommand(char *command, LONG stack, LONG Priority);
  59. static struct Window *ActiveWindow(void);
  60. static struct Screen *ActiveScreen(void);
  61.  
  62.  
  63. extern struct WBStartup *WBMsg;
  64.  
  65.  
  66. /* okay to quit? (not so if palettes open) */
  67. int
  68. OkayToExit()
  69. {
  70.     return (palette_count == 0);
  71. }
  72.  
  73.  
  74. /* hook-function for inserting chars into input-stream */
  75. static SAVEDS ASM void 
  76. putcharfunc(REG(a0) struct Hook *h,
  77.             REG(a2) void *object,
  78.             REG(a1) char c)
  79. {
  80.     struct InputEvent ev;
  81.  
  82.     if (c)                      /* stop at null-terminator */
  83.     {
  84.         ev.ie_NextEvent = NULL;
  85.         InvertKeyMap(c, &ev, NULL);
  86.         AddIEvents(&ev);
  87.     }
  88. }
  89. /* and its associated structure */
  90. static struct Hook putcharhook = {
  91.         {NULL, NULL},
  92.         (APTR)putcharfunc,
  93.         NULL,
  94.         NULL
  95. };
  96.  
  97. /* given a list of input events, reverse their order */
  98. /* NB: the list BETTER terminate... */
  99. static struct InputEvent *
  100. FlipIEvents(struct InputEvent *ie)
  101. {
  102.     struct InputEvent *oldtail, *newtail = NULL;
  103.  
  104.     while (ie)
  105.     {
  106.         /* remove head, set next event */
  107.         oldtail = ie->ie_NextEvent; /* this will be prev event */
  108.         ie->ie_NextEvent = newtail; /* add to head */
  109.         newtail = ie;
  110.         ie = oldtail;           /* what's left */
  111.     }
  112.     return newtail;
  113. }
  114.  
  115. /* adds a string to the input-stream */
  116.  
  117. static int
  118. AddToStream(char *str, UBYTE delay)
  119. {
  120.     struct InputEvent *ie;
  121.  
  122.     if (ie = InvertString(str, NULL))
  123.     {
  124.         ie = FlipIEvents(ie);
  125.  
  126.         if (delay>0)
  127.         {
  128.             struct InputEvent *next;
  129.             while (ie)
  130.             {
  131.                 next = ie->ie_NextEvent; 
  132.                 ie->ie_NextEvent = NULL;
  133.                 AddIEvents(ie);
  134.                 FreeIEvents(ie);
  135.  
  136.                 Delay(delay);
  137.  
  138.                 ie = next;
  139.             }
  140.  
  141.         }
  142.         else
  143.         {
  144.             AddIEvents(ie);
  145.             FreeIEvents(ie);
  146.         }
  147.         return TRUE;
  148.     }
  149.     return FALSE;
  150. }
  151.  
  152. /* find (a) Workbench window */
  153. static struct Window *
  154. FindWBWindow()
  155. {
  156.     struct Screen *s = LockPubScreen("Workbench");
  157.     if (s)
  158.     {
  159.         struct Window *w = s->FirstWindow;
  160.         WBenchToFront();
  161.         Forbid();
  162.         for (; w; w = w->NextWindow)
  163.             if (w->Flags & WFLG_WBENCHWINDOW)
  164.                 break;
  165.         Permit();
  166.         UnlockPubScreen(NULL, s);
  167.         return w;
  168.     }
  169.     return NULL;
  170. }
  171.  
  172. /* bring a palette up on screen */
  173. /* CreateNewProc this function... */
  174. static SAVEDS void
  175. DoPalette()
  176. {
  177.     struct ReqToolsBase *ReqToolsBase;
  178.     struct Screen       *mousescr;
  179.     struct Window       *win;
  180.     STRPTR               title=getString(Palette_Title);
  181.     LONG                 tags[3];
  182.  
  183.     if (ReqToolsBase = (void *)OpenLibrary("reqtools.library", 0L))
  184.     {
  185.         mousescr = ReqToolsBase->IntuitionBase->FirstScreen;
  186.  
  187.         win=mousescr->FirstWindow;
  188.  
  189.         while (win)
  190.         {
  191.             if ((win->Title) && !strcmp(title, win->Title))
  192.             {
  193.                 WindowToFront(win);
  194.                 ActivateWindow(win);
  195.                 return;
  196.             }
  197.             win=win->NextWindow;
  198.         }
  199.  
  200.         palette_count++;
  201.  
  202.         tags[0] = RT_Screen;
  203.         tags[1] = (LONG)mousescr;
  204.         tags[2] = TAG_DONE;
  205.         (void) rtPaletteRequestA(title, NULL, (struct TagItem *)tags);
  206.         CloseLibrary((struct Library *)ReqToolsBase);
  207.     }
  208.     palette_count--;
  209. }
  210.  
  211. /*
  212.  * Asynchronous external command started with its own autocon Input/Output
  213.  * Result will only reflect whether System() call itself succeeded.
  214.  * If System() call fails, result will be -1L; -2L for window failure.
  215.  * We are using -2L as result if our Open of CON: fails
  216.  */
  217. #define AUTOCON "CON:0/25/640/150/Yak Command/AUTO/CLOSE/WAIT/ALT0/25/80/50"
  218. static LONG
  219. beginCommand(char *command, LONG Stack, LONG Priority)
  220. {
  221.     static ULONG stags[] = {
  222.         SYS_Input, NULL,
  223.         SYS_Output, NULL,
  224.         SYS_Asynch, TRUE,
  225.         SYS_UserShell, TRUE,
  226.         NP_Priority, 0L,
  227.         NP_StackSize, 4000L,
  228. #ifndef USE_WB2CLI
  229.         NP_Path, 0L,
  230. #endif
  231.         TAG_DONE
  232.         };
  233.     BPTR file;
  234.     char *filename;
  235.  
  236. #ifdef NOTDEF                   /* will this screw up sometimes? */
  237.     char *t;
  238.     int inquote = FALSE, usecon = TRUE;
  239.  
  240.     /* determine (simple-mindedly) whether there's redirection */
  241.     for (t = command; *t; t++)
  242.     {
  243.         if (*t == '\"')
  244.             if (t <= command || t[-1] != '*')
  245.                 inquote ^= 1;
  246.         if (!inquote)
  247.             if (*t == '>')
  248.             {
  249.                 usecon = FALSE;
  250.                 break;
  251.             }
  252.     }
  253.  
  254.     filename = usecon ? AUTOCON : "NIL:";
  255. #else
  256.     filename = AUTOCON;
  257. #endif
  258.     if (file = Open(filename, MODE_OLDFILE))
  259.     {
  260.         stags[1] = (ULONG)file;
  261.         stags[9] = Priority;
  262.         
  263.         if (Stack>0)
  264.         {
  265.             stags[11] = Stack;
  266.         }
  267.  
  268. #ifndef USE_WB2CLI
  269.         if (WBMsg)
  270.         {
  271.             stags[13] = (ULONG) CloneWorkbenchPath(WBMsg); 
  272.         }
  273. #endif
  274.         return(SystemTagList(command, (struct TagItem *)stags));
  275.     }
  276.     else return(-2);
  277. }
  278.  
  279.  
  280. /* execute a command */
  281. void
  282. act_ExecuteCommand(YakHotKey *yhk)
  283. {
  284.     LONG rc;
  285.  
  286.     if (yhk->yhk_Option[1].ArgStr[0])
  287.     {
  288.         ChangeScreen(&yhk->yhk_Option[0]);
  289.  
  290.         if (yhk->yhk_Option[1].Flags & HKO_CLI_COMMAND)
  291.         {
  292.             rc = beginCommand(yhk->yhk_Option[1].ArgStr[0], 
  293.                               yhk->yhk_Option[1].ArgNum[0], 
  294.                               yhk->yhk_Option[1].ArgNum[1]);
  295.         }
  296.         else
  297.         {
  298.             rc = SendARexxCommand(yhk->yhk_Option[1].ArgStr[1], yhk->yhk_Option[1].ArgStr[0]);
  299.         }
  300.         if (rc != 0)
  301.             PostError("%s\n\"%s\"",
  302.                       getString(Couldnt_execute_command_ERR), 
  303.                       yhk->yhk_Option[1].ArgStr[0]);
  304.     }
  305.     else 
  306.         PostError("%s\"%s\".", 
  307.                   getString(No_cmd_specified_for_hotkey_ERR), 
  308.                   yhk->yhk_KeyDef);
  309. }
  310.  
  311.  
  312. void
  313. act_CloseWindow(YakHotKey *yhk)
  314. {
  315.         /* CloseEvent is declared as static to save some bytes and speed up code */
  316.     static struct InputEvent CloseEvent = { NULL, IECLASS_CLOSEWINDOW, 0, 0, 0, 0 };
  317.     struct Window *window;
  318.     struct Window *CurrentWindow = NULL;
  319.  
  320.     CurrentWindow = ActiveWindow();
  321.  
  322.     if (window = SelectWindow(&yhk->yhk_Option[0]))
  323.     {
  324.         if (window && (window->Flags & CLOSEGADGET))
  325.         {
  326.             ActivateWindow(window);
  327.             AddIEvents(&CloseEvent);
  328.  
  329.             do 
  330.             {
  331.                 Delay(1);
  332.             } while (window == ActiveWindow());
  333.  
  334.             if (CurrentWindow && (window != CurrentWindow))
  335.             {
  336.                 ActivateWindow(CurrentWindow);
  337.             }
  338.             else
  339.             {   
  340.                 if (autopoint)
  341.                 {
  342.                     ActivateMouseWindow (KEY);
  343.                 }
  344.             }
  345.         }
  346.     }
  347. }
  348.  
  349.  
  350.  
  351. /*
  352.  * This function simulates Intuition mutal exclusion for menu items.
  353.  */ 
  354.  
  355. static __regargs void
  356. UnCheckExcludedItems(UWORD  menu, 
  357.                      UWORD  item, 
  358.                      UWORD  sub, 
  359.                      ULONG MutualExclude, 
  360.                      struct Window *window)
  361. {
  362.     struct MenuItem *menuitem;
  363.     UWORD  menuNumber;
  364.     UBYTE  i=0;
  365.  
  366.     while (MutualExclude > 0)
  367.     {
  368.         if (MutualExclude & 1)
  369.         {
  370.             /* Item to exclude */
  371.  
  372.             if (sub == NOSUB)
  373.             {
  374.                 item = i;
  375.             }
  376.             else
  377.             {
  378.                 sub = i;
  379.             }
  380.  
  381.             menuNumber = FULLMENUNUM( menu, item, sub );
  382.             menuitem = ItemAddress(window->MenuStrip, menuNumber);
  383.  
  384.             if ((menuitem) &&                       /* item must exist      */
  385.                 (menuitem->Flags & ITEMENABLED) && /* item must be enabled */
  386.                 (menuitem->Flags & CHECKED))       /* item must be checked */
  387.             {
  388.                 menuitem->Flags &= ~CHECKED;
  389.             }
  390.         }
  391.         MutualExclude = MutualExclude >> 1;
  392.         i++;
  393.     }
  394. }
  395.  
  396.  
  397. void
  398. act_MenuShortcut(YakHotKey *yhk)
  399. {
  400.     /* MenuEvent is declared as static to save some bytes and speed up code */
  401.     static struct InputEvent MenuEvent = { NULL, IECLASS_MENULIST, 0, 0, IEQUALIFIER_LEFTBUTTON, 0 };
  402.     struct Window *window;
  403.     struct MenuItem *menuitem;
  404.     UWORD  menuNumber, menu, item, sub;
  405.  
  406.     window = ActiveWindow();
  407.  
  408.     menu = (UWORD) yhk->yhk_Option[0].ArgNum[0];
  409.     item = (UWORD) yhk->yhk_Option[0].ArgNum[1];
  410.  
  411.     if (yhk->yhk_Option[0].Flags & HKO_SUBITEM)
  412.     {
  413.         sub = (UWORD) yhk->yhk_Option[0].ArgNum[2];
  414.     }
  415.     else
  416.     {
  417.         /* no subitem specified */
  418.         sub = NOSUB;
  419.     }
  420.  
  421.     if (window && (window->MenuStrip))
  422.     {
  423.         menuNumber = FULLMENUNUM( menu, item, sub );
  424.         menuitem = ItemAddress(window->MenuStrip, menuNumber);
  425.  
  426.         if ((menuitem) &&                     /* item must exist             */
  427.             (menuitem->Flags & ITEMENABLED)) /* item must be enabled        */
  428.         {
  429.             /* We don't want multi selection */
  430.             menuitem->NextSelect = MENUNULL;
  431.  
  432.             /* Take care of checkit items */
  433.             if (menuitem->Flags & CHECKIT)
  434.             {
  435.                 if (menuitem->Flags & MENUTOGGLE) 
  436.                 {
  437.                     if (menuitem->Flags & CHECKED)
  438.                     {
  439.                         /* If it's already checked, uncheck it */
  440.                         menuitem->Flags &= ~CHECKED;
  441.                     }
  442.                     else
  443.                      {
  444.                         /* If it's unchecked, check it */
  445.                         menuitem->Flags |= CHECKED;
  446.                     }
  447.                 }
  448.                 else 
  449.                 {
  450.                     /* Mutual Exclude */
  451.                     if ((menuitem->Flags & CHECKED) == FALSE)
  452.                     {
  453.                         /* check it */
  454.                         menuitem->Flags |= CHECKED;
  455.  
  456.                         /* and then take care of excluded items */
  457.                         UnCheckExcludedItems(menu, item, sub, menuitem->MutualExclude, window);
  458.                     }
  459.                 }
  460.             }
  461.  
  462.             /* Send our event */
  463.             MenuEvent.ie_Code         = menuNumber;
  464.             MenuEvent.ie_EventAddress = window;
  465.  
  466.             AddIEvents(&MenuEvent);
  467.         }
  468.     }
  469.  
  470. }
  471.  
  472. void
  473. act_ZipWindow(YakHotKey *yhk)
  474. {
  475.     struct Window *window;
  476.     ULONG lock;
  477.  
  478.     lock = LockIBase(0);
  479.     if (window = SelectWindow(&yhk->yhk_Option[0]))
  480.     {
  481.         if (window->Flags & WFLG_HASZOOM)
  482.             ZipWindow(window);
  483.     }
  484.     UnlockIBase(lock);
  485. }
  486.  
  487. void
  488. act_ShrinkWindow(YakHotKey *yhk)
  489. {
  490.     struct Window *window;
  491.     ULONG lock;
  492.  
  493.     lock = LockIBase(0);
  494.     if (window = SelectWindow(&yhk->yhk_Option[0]))
  495.     {
  496.         if (window->Flags & WFLG_SIZEGADGET)
  497.             ChangeWindowBox(window,
  498.                             window->LeftEdge,
  499.                             window->TopEdge,
  500.                             window->MinWidth,
  501.                             window->MinHeight);
  502.     }
  503.     UnlockIBase(lock);
  504. }
  505.  
  506. void
  507. act_ExpandWindow(YakHotKey *yhk)
  508. {
  509.     struct Window  *win;
  510.     ULONG           lock;
  511.  
  512.     lock = LockIBase(0);
  513.  
  514.     if (win = SelectWindow(&yhk->yhk_Option[0]))
  515.     {
  516.         if (win->Flags & WFLG_SIZEGADGET)
  517.         {
  518.             EnlargeWindow(win, yhk->yhk_Option[1].Flags);
  519.         }
  520.     }
  521.  
  522.     UnlockIBase(lock);
  523. }
  524.  
  525.  
  526. void
  527. act_MoveWindow(YakHotKey *yhk)
  528. {
  529.     struct Window  *win;
  530.     WORD            top, left,
  531.                     width, height;
  532.     ULONG           lock;
  533.     struct IBox     box;
  534.     struct Screen  *s;
  535.  
  536.     lock = LockIBase(0);
  537.  
  538.     if (win=SelectWindow(&yhk->yhk_Option[0]))
  539.     {
  540.  
  541.         if (win->Flags & WFLG_DRAGBAR)
  542.         {
  543.             top    = win->TopEdge;
  544.             left   = win->LeftEdge;
  545.             width  = win->Width;
  546.             height = win->Height;
  547.             s      = win->WScreen;
  548.  
  549.  
  550.             GetScreenBox(s, &box, (yhk->yhk_Option[1].Flags & HKO_MOVE_VISIBLE_BAR));
  551.  
  552.             if (yhk->yhk_Option[1].Flags & HKO_MOVE_LEFT)
  553.                 left = box.Left;
  554.  
  555.             if (yhk->yhk_Option[1].Flags & HKO_MOVE_HORIZONTAL_CENTER)
  556.                 left = box.Left + (box.Width-width)>>1;
  557.  
  558.             if (yhk->yhk_Option[1].Flags & HKO_MOVE_RIGHT)
  559.                 left = box.Left + box.Width - width;
  560.  
  561.             if (yhk->yhk_Option[1].Flags & HKO_MOVE_TOP)
  562.                 top = box.Top;
  563.  
  564.             if (yhk->yhk_Option[1].Flags & HKO_MOVE_VERTICAL_CENTER)
  565.                 top = box.Top + (box.Height-height)/2;
  566.  
  567.             if (yhk->yhk_Option[1].Flags & HKO_MOVE_BOTTOM)
  568.                 top = box.Top + box.Height - height;
  569.  
  570.             if (win->LeftEdge != left || win->TopEdge != top)
  571.                 ChangeWindowBox(win,
  572.                                 left,
  573.                                 top,
  574.                                 width,
  575.                                 height);
  576.  
  577.         }
  578.     }
  579.  
  580.     UnlockIBase(lock);
  581. }
  582.  
  583.  
  584. /*
  585.  * This function tells if a window has to be cycled according to 
  586.  * the cycling options
  587.  */
  588.  
  589. __regargs BOOL
  590. MatchWindow(struct Window *win, UWORD Options, STRPTR Pattern)
  591. {
  592.     BOOL result;
  593.     struct Task *WinTask;
  594.     STRPTR TaskName;
  595.  
  596.     if (win)
  597.     {
  598.         if (Options & HKO_EXCLUDE_WB_DRAWERS) 
  599.         {
  600.             result = !(win->Flags & WFLG_WBENCHWINDOW);
  601.         }
  602.         else
  603.         {
  604.             result = TRUE;
  605.         }
  606.    
  607.         if ((result==TRUE) && !(Options & HKO_ACTIVATE_ONLY)) 
  608.         {
  609.             result = !(win->Flags & WFLG_BACKDROP);
  610.         }
  611.  
  612.         if ((result==TRUE) && (Options & HKO_BY_WINDOW_TASK_NAME))
  613.         {
  614.             /* This is the task attached to our window */
  615.             if ((WinTask = win->UserPort->mp_SigTask) &&
  616.                 (TaskName = WinTask->tc_Node.ln_Name))
  617.             {
  618.                 /* Does its name match our pattern? */
  619.                 result = MatchPattern(Pattern, TaskName);
  620.             }
  621.             else
  622.             {
  623.                 result = FALSE;
  624.             }
  625.         }
  626.     }
  627.     else
  628.     {
  629.         result = FALSE;
  630.     }
  631.  
  632.     return(result);
  633. }
  634.  
  635.  
  636. /* This function cycle through specified windows 
  637.  * WARNING: it must be called under Forbid()/LockIBase()
  638.  */
  639. void
  640. SelectiveCycleWindows(struct Screen *s, 
  641.                       UWORD Options, 
  642.                       STRPTR Pattern)
  643. {
  644.     struct Layer  *l;
  645.     struct Window *curwin = NULL;
  646.     struct Window *next;
  647.     struct Window *backmost = NULL;
  648.    
  649.     if (l = s->LayerInfo.top_layer)
  650.     {
  651.         /* starting from top layer one, find backmost window 
  652.          * that matches our criterias
  653.          */
  654.         for (l = s->LayerInfo.top_layer; l; l = l->back)
  655.         {
  656.             curwin = (struct Window *)l->Window;
  657.             if (MatchWindow(curwin, Options, Pattern))
  658.                 backmost = curwin;
  659.         }   
  660.  
  661.         l = backmost->WLayer;
  662.  
  663.         if (Options & HKO_ACTIVATE_ONLY)
  664.         {
  665.             if ((IntuitionBase->ActiveWindow) &&
  666.                 (IntuitionBase->ActiveWindow->WScreen == s))
  667.             {
  668.                 curwin = IntuitionBase->ActiveWindow;
  669.             }                    
  670.             else
  671.             {
  672.                 curwin = s->FirstWindow;
  673.             }
  674.         }
  675.         else
  676.         {
  677.             curwin = backmost;
  678.         }
  679.  
  680.         if (curwin)
  681.         {
  682.             l = curwin->WLayer; 
  683.             next = curwin;
  684.  
  685.             if (Options & HKO_ACTIVATE_ONLY)
  686.             {
  687.                 while (l && 
  688.                        (!MatchWindow(next, Options, Pattern) ||
  689.                         (next == curwin)))
  690.                 {
  691.                     next = (struct Window *)l->Window;
  692.                     l = l->front;
  693.                 } 
  694.                 if (next == curwin)
  695.                 {
  696.                     /* We have reached TopLayer window, so go back to back most one */
  697.                     next = backmost;
  698.                 }
  699.             }
  700.             else
  701.             {
  702.                 while (l && 
  703.                        !MatchWindow(next, Options, Pattern))
  704.                 {
  705.                     next = (struct Window *)l->Window;
  706.                     l = l->front;
  707.                 } 
  708.                 ScreenToFront(next->WScreen);
  709.                 WindowToFront(next);
  710.             }
  711.             ActivateWindow(next);
  712.         }
  713.     }
  714. }
  715.  
  716.  
  717. /* 
  718.  * This function cycle through specified windows but in the inverse 
  719.  * direction as the one used by SelectiveCycleWindows().
  720.  * WARNING: it must be called under Forbid()/LockIBase()
  721.  * 
  722.  */
  723.  
  724. void
  725. SelectiveBackCycleWindows(struct Screen *s, 
  726.                           UWORD Options, 
  727.                           STRPTR Pattern)
  728. {
  729.     struct Layer  *l;
  730.     struct Window *frontmost;
  731.     struct Window *previous;
  732.     struct Window *curwin = NULL;
  733.    
  734.     if (l = s->LayerInfo.top_layer)
  735.     {
  736.         /* starting from top layer one, find frontmost window that matches
  737.          * our criterias.
  738.          */
  739.         frontmost = NULL;
  740.  
  741.         while (l && !MatchWindow(frontmost, Options, Pattern))
  742.         {
  743.             frontmost = (struct Window *)l->Window;        
  744.             l = l->back;    
  745.         }
  746.  
  747.         if (frontmost)
  748.         {
  749.             if (Options & HKO_ACTIVATE_ONLY)
  750.             {
  751.                 if ((IntuitionBase->ActiveWindow) &&
  752.                     (IntuitionBase->ActiveWindow->WScreen == s))
  753.                 {
  754.                     curwin = IntuitionBase->ActiveWindow;
  755.                 }    
  756.                 else
  757.                 {
  758.                     curwin = s->FirstWindow;
  759.                 }
  760.             }
  761.             else
  762.             {
  763.                 curwin = frontmost;
  764.                 if (MatchWindow(curwin, Options, Pattern))
  765.                 {
  766.                     WindowToBack(curwin);
  767.                 }
  768.             }
  769.  
  770.             /* find the frontmost matching window by starting from the top layer 
  771.              * We must take care to exclude the window we start from.
  772.              */
  773.  
  774.  
  775.             l = curwin->WLayer;
  776.             previous = curwin;
  777.         
  778.             while (l && 
  779.                    (!MatchWindow(previous, Options, Pattern) ||
  780.                     (previous == curwin))) 
  781.             {
  782.                 previous = (struct Window *)l->Window;
  783.                 l = l->back;
  784.             } 
  785.  
  786.             if ((l == NULL) && ((previous == NULL) || (previous == curwin)))
  787.             {
  788.                 /* We have reached the backmost window.*/
  789.                 previous = frontmost;    
  790.             }
  791.  
  792.             if (!(Options & HKO_ACTIVATE_ONLY))
  793.             {
  794.                 WindowToFront(previous);
  795.             }
  796.             ActivateWindow(previous);
  797.         }
  798.     }
  799. }
  800.  
  801.  
  802. void
  803. act_CycleWindows(YakHotKey *yhk)
  804. {
  805.     struct Screen *s;
  806.     PatternData   pdata = {"",NULL};
  807.     ULONG lock;
  808.  
  809.     if (s = SelectScreen(&yhk->yhk_Option[0]))
  810.     {
  811.         if (yhk->yhk_Option[1].Flags & HKO_BY_WINDOW_TASK_NAME)
  812.         {
  813.             InitPattern(yhk->yhk_Option[1].ArgStr[0], &pdata);
  814.         }
  815.  
  816.         lock = LockIBase(0);
  817.         Forbid();
  818.  
  819.         if (yhk->yhk_Option[1].Flags & HKO_BACK_CYCLE) 
  820.         {
  821.             SelectiveBackCycleWindows(s, yhk->yhk_Option[1].Flags, pdata.pat);
  822.         } 
  823.         else
  824.         {
  825.             SelectiveCycleWindows(s, yhk->yhk_Option[1].Flags, pdata.pat);
  826.         }
  827.  
  828.         Permit();
  829.         UnlockIBase(lock);
  830.     }
  831.  
  832. }    
  833.  
  834.  
  835. /* taglist for CreateNewProc */
  836. static LONG palette_taglist[] = {
  837.         NP_Entry, (LONG)DoPalette,
  838.         NP_Name, (LONG)"Yak Palette",
  839.         TAG_DONE
  840. };
  841.  
  842. void
  843. act_OpenPalette(YakHotKey *yhk)
  844. {
  845.     ChangeScreen(&yhk->yhk_Option[0]);
  846.  
  847.     CreateNewProc((struct TagItem *)palette_taglist);
  848. }
  849.  
  850. void
  851. act_ScreenToFront(YakHotKey *yhk)
  852. {
  853.     struct Screen *s;
  854.  
  855.     if (s=SelectScreen(&yhk->yhk_Option[0]))
  856.     {
  857.         MyScreenToFront(s);
  858.     }
  859. }
  860.  
  861. void
  862. act_ScreenToBack(YakHotKey *yhk)
  863. {
  864.     struct Screen *s;
  865.  
  866.     if (s=SelectScreen(&yhk->yhk_Option[0]))
  867.     {
  868.         MyScreenToBack(s);
  869.     }
  870. }
  871.  
  872. void
  873. act_ActivateWorkbench(YakHotKey *yhk)
  874. {
  875.     struct Window *w;
  876.  
  877.     if (w = FindWBWindow())
  878.     {
  879.         WBenchToFront();
  880.         ActivateWindow(w);
  881.     }
  882. }
  883.  
  884. void
  885. act_MoveScreen(YakHotKey *yhk)
  886. {
  887.     struct Screen *scr;
  888.  
  889.     if (scr = SelectScreen(&yhk->yhk_Option[0]))
  890.     {
  891.         YakMoveScreen(scr, yhk->yhk_Option[1].Flags);
  892.     }
  893. }
  894.  
  895. void
  896. act_BlankDisplay(YakHotKey *yhk)
  897. {
  898.     BlankScreen();
  899. }
  900.  
  901. void
  902. act_InsertText(YakHotKey *yhk)
  903. {
  904.     if (yhk->yhk_Option[0].ArgStr[0])
  905.     {
  906.         if (!AddToStream(yhk->yhk_Option[0].ArgStr[0], (UBYTE)yhk->yhk_Option[0].ArgNum[0]))
  907.             PostError("%s:\n \"%s\"", 
  908.                       getString(Text_insertion_str_invalid_ERR), yhk->yhk_Option[0].ArgStr[0]);
  909.     }
  910.     else PostError("%s \"%s\" %s", 
  911.                    getString(Yak_text_hotkey_ERR),
  912.                    yhk->yhk_KeyDef,
  913.                    getString(Has_no_text_specified_ERR));
  914. }
  915.  
  916. void
  917. act_InsertDate(YakHotKey *yhk)
  918. {
  919.     struct DateTime dat;
  920.     DateStamp(&dat.dat_Stamp);
  921.  
  922.     if (LocaleBase)
  923.     {
  924.         if (yhk->yhk_Option[0].ArgStr[0])
  925.             FormatDate(locale, yhk->yhk_Option[0].ArgStr[0], &dat.dat_Stamp, &putcharhook);
  926.         else PostError("%s \"%s\" %s", 
  927.                        getString(Yak_date_hotkey_ERR),
  928.                        yhk->yhk_KeyDef,
  929.                        getString(Has_no_format_specified_ERR));
  930.     }
  931.     else
  932.     {
  933.         /* pre-2.1 OS */
  934.         char datestr[LEN_DATSTRING];
  935.  
  936.         dat.dat_Format = FORMAT_DOS;
  937.         dat.dat_Flags = 0;
  938.         dat.dat_StrDate = datestr;
  939.         dat.dat_StrDay = dat.dat_StrTime = NULL;
  940.         DateToStr(&dat);
  941.         AddToStream(datestr, 0);
  942.     }
  943. }
  944.  
  945.  
  946. void
  947. act_ShowInterface(YakHotKey *yhk)
  948. {
  949.     ChangeScreen(&yhk->yhk_Option[0]);
  950.     ShowYakInterface();
  951. }
  952.  
  953.  
  954.  
  955. /* Set the active screen as default public screen if it a public screen 
  956. ** else do nothing.
  957. **/
  958. void
  959. act_CurrentScreenAsDefPub(YakHotKey *yhk)
  960. {
  961.     UBYTE *PSName;
  962.     struct Screen *s;
  963.  
  964.     /* Get the active screen */
  965.     s = ActiveScreen();
  966.  
  967.     /* Get the name of our screen if it is a public screen */
  968.     PSName = GetPubScreenName(s);
  969.  
  970.     if (PSName)
  971.     {
  972.         /* active screen is a public screen so 
  973.          * make it default public screen
  974.          */
  975.         SetDefaultPubScreen(PSName);
  976.     }
  977. }
  978.  
  979.  
  980.  
  981. static void __regargs
  982. YakMoveScreen(struct Screen *scr, UWORD flags)
  983. {
  984.     struct Window    *win;
  985.     struct Rectangle  rect;
  986.     struct IBox       b_box, f_box;
  987.     ULONG             modeid;
  988.     WORD              dx=0,dy=0;
  989.  
  990.     if ( (modeid = GetVPModeID(&scr->ViewPort)) != INVALID_ID &&
  991.          QueryOverscan(modeid, &rect, OSCAN_TEXT))
  992.     {
  993.         if((flags & HKO_MOVE_VISIBLE_BAR) &&
  994.            (win=ActiveWindow()) &&
  995.            (win->WScreen == scr))
  996.         {
  997.             GetScreenBox(scr, &b_box, FALSE);
  998.             f_box.Left   = win->LeftEdge;
  999.             f_box.Top    = win->TopEdge;
  1000.             f_box.Width  = win->Width;
  1001.             f_box.Height = win->Height;
  1002.         }
  1003.         else
  1004.         {
  1005.             b_box.Left   = rect.MinX;
  1006.             b_box.Top    = rect.MinY;
  1007.             b_box.Width  = rect.MaxX - rect.MinX + 1;
  1008.             b_box.Height = rect.MaxY - rect.MinY + 1;
  1009.             f_box.Left   = scr->LeftEdge;
  1010.             f_box.Top    = scr->TopEdge;
  1011.             f_box.Width  = scr->Width;
  1012.             f_box.Height = scr->Height;
  1013.         }
  1014.  
  1015.         if (flags & HKO_MOVE_LEFT)
  1016.             dx = b_box.Left - f_box.Left;
  1017.  
  1018.         if (flags & HKO_MOVE_HORIZONTAL_CENTER)
  1019.             dx = b_box.Left - f_box.Left + ((b_box.Width - f_box.Width) >> 1);
  1020.  
  1021.         if (flags & HKO_MOVE_RIGHT)
  1022.             dx = b_box.Left - f_box.Left + b_box.Width - f_box.Width;
  1023.  
  1024.         if (flags & HKO_MOVE_TOP)
  1025.             dy = b_box.Top - f_box.Top;
  1026.  
  1027.         if (flags & HKO_MOVE_VERTICAL_CENTER)
  1028.             dx = b_box.Top - f_box.Top + ((b_box.Height - f_box.Height) >> 1);
  1029.  
  1030.         if (flags & HKO_MOVE_BOTTOM)
  1031.             dy = b_box.Top - f_box.Top + b_box.Height - f_box.Height;
  1032.  
  1033.         MoveScreen(scr, dx, dy);
  1034.     }
  1035. }
  1036.  
  1037.  
  1038. static void __regargs
  1039. EnlargeWindow(struct Window *win, UWORD flags)
  1040. {
  1041.     WORD            width  = win->Width,
  1042.                     height = win->Height,
  1043.                     top    = win->TopEdge,
  1044.                     left   = win->LeftEdge,
  1045.                     l;
  1046.     struct IBox     box;
  1047.     struct Screen  *s = win->WScreen;
  1048.  
  1049.     GetScreenBox(s, &box, flags & HKO_RESIZE_VISIBLE_BAR);
  1050.  
  1051.     if (flags & HKO_RESIZE_HORIZONTAL)
  1052.     {
  1053.         width = win->MaxWidth;
  1054.         if (width == -1 || width > box.Width)
  1055.             width = box.Width;
  1056.         if (left < box.Left)
  1057.         {
  1058.             left = box.Left;
  1059.         } 
  1060.         else
  1061.         {
  1062.             if ((l = box.Left + box.Width - left - width) < 0)
  1063.                 left += l;
  1064.         }
  1065.     }
  1066.     if (flags & HKO_RESIZE_VERTICAL)
  1067.     {
  1068.         height = win->MaxHeight;
  1069.         if (height == -1 || height > box.Height)
  1070.             height = box.Height;
  1071.  
  1072.         if (top < box.Top)
  1073.         {
  1074.             top = box.Top;
  1075.         } else
  1076.         {
  1077.             if ((l = box.Top + box.Height - top - height) < 0)
  1078.                 top += l;
  1079.         }
  1080.     }
  1081.     if (win->LeftEdge != left || win->TopEdge != top ||
  1082.         win->Width != width || win->Height != height)
  1083.         ChangeWindowBox(win,
  1084.                         left,
  1085.                         top,
  1086.                         width,
  1087.                         height);
  1088. }
  1089.  
  1090.  
  1091.  
  1092. static struct Window *
  1093. ActiveWindow(void)
  1094. {
  1095.     ULONG lock;
  1096.     struct Window *window=NULL;
  1097.  
  1098.     lock = LockIBase(0);
  1099.     window = IntuitionBase->ActiveWindow;
  1100.     UnlockIBase(lock);
  1101.  
  1102.     return window;
  1103. }
  1104.  
  1105.  
  1106.  
  1107.  
  1108. static struct Window *
  1109. WindowByTitle(STRPTR title)
  1110. {
  1111.     struct Screen *screen      = NULL;
  1112.     struct Window *window      = NULL;
  1113.     BOOL           WindowFound = FALSE;
  1114.     PatternData    pdata       = {"",NULL};
  1115.  
  1116.     if (InitPattern(title, &pdata))
  1117.     {
  1118.         ULONG lock = LockIBase(0);
  1119.  
  1120.         screen = IntuitionBase->FirstScreen;
  1121.  
  1122.         while (screen && !WindowFound)
  1123.         {
  1124.             window = screen->FirstWindow;
  1125.  
  1126.             while (window && !WindowFound)
  1127.             {
  1128.                 if (window->Title)
  1129.                 {
  1130.                     WindowFound = MatchPattern(pdata.pat, window->Title);
  1131.                 }
  1132.                 if (WindowFound == FALSE)
  1133.                 {
  1134.                     window = window->NextWindow;
  1135.                 }
  1136.             }
  1137.             screen = screen->NextScreen;
  1138.         }
  1139.     
  1140.         UnlockIBase(lock);
  1141.  
  1142.         FreeVec(pdata.pat);
  1143.     }
  1144.     
  1145.     if (WindowFound)
  1146.     {
  1147.         return(window);
  1148.     }
  1149.     else
  1150.     {
  1151.         return(NULL);
  1152.     }
  1153. }
  1154.  
  1155.  
  1156. static struct Screen *
  1157. ActiveScreen(void)
  1158. {
  1159.     ULONG lock;
  1160.     struct Screen *screen=NULL;
  1161.   
  1162.     lock = LockIBase(0);
  1163.     screen = IntuitionBase->ActiveScreen;
  1164.     UnlockIBase(lock);
  1165.     
  1166.     return (screen);
  1167. }
  1168.  
  1169.  
  1170.  
  1171. static struct Screen *
  1172. ScreenByTitle(STRPTR title)
  1173. {
  1174.     struct Screen *screen      = NULL;
  1175.     PatternData    pdata       = {"",NULL};
  1176.     BOOL           ScreenFound = FALSE;
  1177.  
  1178.     if (InitPattern(title, &pdata))
  1179.     {
  1180.         ULONG lock = LockIBase(0);
  1181.  
  1182.         screen = IntuitionBase->FirstScreen;
  1183.  
  1184.         while (screen && !ScreenFound)
  1185.         {
  1186.             if (screen->DefaultTitle)
  1187.             {
  1188.                 ScreenFound=MatchPattern(pdata.pat, screen->DefaultTitle);
  1189.             }
  1190.             if (ScreenFound == FALSE) 
  1191.             {
  1192.                 screen = screen->NextScreen;
  1193.             }
  1194.         }
  1195.     
  1196.         UnlockIBase(lock);
  1197.  
  1198.         FreeVec(pdata.pat);
  1199.     }
  1200.     
  1201.     if (ScreenFound)
  1202.     {
  1203.         return(screen);
  1204.     }
  1205.     else
  1206.     {
  1207.         return(NULL);
  1208.  
  1209.     }
  1210. }
  1211.  
  1212. struct Screen *
  1213. RearmostScreen(void)
  1214. {
  1215.     ULONG lock;
  1216.     struct Screen *screen=NULL, *ns;
  1217.   
  1218.     lock = LockIBase(0);
  1219.    
  1220.     screen = IntuitionBase->FirstScreen;
  1221.  
  1222.     ns = screen->NextScreen;
  1223.     while (ns)
  1224.     {
  1225.         screen = ns;
  1226.         ns     = screen->NextScreen;
  1227.     }
  1228.  
  1229.     UnlockIBase(lock);
  1230.  
  1231.     return screen;
  1232. }
  1233.  
  1234.  
  1235. static struct Screen *
  1236. FrontmostScreen(void)
  1237. {
  1238.     ULONG lock;
  1239.     struct Screen *screen=NULL;
  1240.   
  1241.     lock = LockIBase(0);
  1242.     screen = IntuitionBase->FirstScreen;
  1243.     UnlockIBase(lock);
  1244.  
  1245.     return screen;
  1246. }
  1247.  
  1248.  
  1249. static struct Window *
  1250. SelectWindow(YakOption *opt)
  1251. {
  1252.     struct Window *window=NULL;
  1253.  
  1254.     switch (opt->Flags)
  1255.     {
  1256.         case HKO_ACTIVE:
  1257.             window = ActiveWindow();
  1258.             break;
  1259.  
  1260.         case HKO_UNDER_MOUSE:
  1261.             window = WindowUnderMouse();
  1262.             break;
  1263.  
  1264.         case HKO_BY_TITLE|HKO_PATTERN:
  1265.             window = WindowByTitle(opt->ArgStr[0]);
  1266.             break;
  1267.     }
  1268.     return window;
  1269. }
  1270.  
  1271.  
  1272. static struct Screen *
  1273. SelectScreen(YakOption *opt)
  1274. {
  1275.     struct Screen *screen=NULL;
  1276.  
  1277.     switch (opt->Flags)
  1278.     {
  1279.       case HKO_ACTIVE:
  1280.         screen = ActiveScreen();
  1281.         break;
  1282.  
  1283.       case HKO_UNDER_MOUSE:
  1284.         screen = ScreenUnderMouse();
  1285.         break;
  1286.  
  1287.       case HKO_BY_TITLE|HKO_PATTERN:
  1288.         screen = ScreenByTitle(opt->ArgStr[0]);
  1289.         break;
  1290.             
  1291.       case HKO_REARMOST:
  1292.         screen = RearmostScreen();
  1293.         break;
  1294.  
  1295.       case HKO_FRONTMOST:
  1296.         screen = FrontmostScreen();
  1297.         break;
  1298.     }
  1299.  
  1300.     return screen;
  1301. }
  1302.  
  1303.  
  1304. static void
  1305. ChangeScreen(YakOption *opt)
  1306. {
  1307.     struct Screen *scr;
  1308.     char *scrname;
  1309.  
  1310.     if (!(opt->Flags & HKO_NO_SCREEN_CHANGE))
  1311.         {
  1312.                 switch (opt->Flags)
  1313.                 {
  1314.                   case HKO_WORKBENCH_TO_FRONT:
  1315.                         scrname = "Workbench";
  1316.                         break;
  1317.  
  1318.                   case HKO_DEFAULT_PUBSCR_TO_FRONT:
  1319.                         scrname = NULL;
  1320.                         break;
  1321.                 }
  1322.  
  1323.                 if (scr = LockPubScreen(scrname))
  1324.                 {
  1325.                         ScreenToFront(scr);
  1326.                         UnlockPubScreen(NULL, scr);
  1327.                 }
  1328.         }
  1329. }
  1330.  
  1331.  
  1332. /*
  1333.  * the generic hotkey action stub
  1334.  */
  1335. void
  1336. PerformAction(YakHotKey *yhk)
  1337. {
  1338.     /* and perform action (gobbledegook!? that's C for you...) */
  1339.     (*(yhktypes[yhk->yhk_Type].yhkt_Command))(yhk);
  1340. }
  1341.  
  1342.